using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Trigits
{
    public abstract class TriominoeContainer
    {
        protected Triominoe[] triominoes;
        protected Rectangle bounds;
        protected const float movespeed = 0.5f;


        public TriominoeContainer(Rectangle bounds, int max, SpriteFont font)
        {
            this.bounds = bounds;

            triominoes = new Triominoe[maxNum(max)];
        }

        protected int maxNum(int a)
        {
            int num = 0;

            for(int i = 0; i <= a; i++)
            {
                num += triangularNum(i + 1);
            }

            return num;
        }

        protected int triangularNum(int a)
        {
            int num = 0;

            for (int i = 1; i <= a; i++)
                num += i;

            return num;
        }

        public void draw(GraphicsDevice graphics, SpriteBatch spriteBatch, SpriteFont font, BasicEffect effect)
        {
            for(int i = 0; i < triominoes.Length; i++)
            if(triominoes[i] != null)    
				triominoes[i].Draw(
                    graphics, 
                    spriteBatch, 
                    font, effect);
        }

        public Triominoe getTriominoe(float x, float y)
        {
            for (int i = 0; i < triominoes.Length; i++)
            {
                if (triominoes[triominoes.Length - i - 1] != null &&
                    triominoes[triominoes.Length - i - 1].containsPoint(x, y))
                    return triominoes[triominoes.Length - i - 1];
            }

            return null;
        }

        public Triominoe getHighestTriominoe()
        {
            Triominoe highest = triominoes[0];

            for (int i = 1; i < triominoes.Length; i++)
            {
                if (triominoes[i] != null)
                {
                    if (highest == null || highest.getValue() < triominoes[i].getValue())
                        highest = triominoes[i];
                }
            }

            return highest;
        }

        public int numberOfTriominoes()
        {
            int num = 0;
            for (int i = 0; i < triominoes.Length; i++)
            {
                if (triominoes[i] != null)
                {
                    num++;
                }
            }

            return num;
        }

        public Triominoe getTriominoe()
        {
            for (int i = 0; i < triominoes.Length; i++)
            {
                if (triominoes[i] != null)
                {
                    Triominoe t = triominoes[i];
                    triominoes[i] = null;
                    return t;
                }
            }

            return null;
        }

        public Triominoe[] getTriominoes()
        {
            return triominoes;
        }


        public virtual void addTriominoe(Triominoe triominoe, bool faceUp)
        {
            
            int count = 0;
            for (int i = 0; i < triominoes.Length; i++)
            {
                if (triominoes[i] == null)
                {
                    count = i;
                    break;
                }
            }
            triominoe.flip(faceUp);
            triominoes[count] = triominoe;
            
        }
       
        public void removeTriominoe(Triominoe triominoe)
        {
            int count = 0;
            for (int i = 0; i < triominoes.Length; i++)
            {
                if (triominoes[i] == triominoe)
                {
                    count = i;
                    break;
                }
            }
            triominoes[count] = null;         
        }
        public void moveTriominoeToContainer(Triominoe triominoe, TriominoeContainer target)
        {
            this.removeTriominoe(triominoe);
            target.addTriominoe(triominoe, true);
        }
        public void moveTriominoeToContainer(Triominoe triominoe, TriominoeContainer target, float xPosition)
        {
            this.removeTriominoe(triominoe);
            target.addTriominoe(triominoe, false);
            triominoe.setLocation(new Vector2(xPosition, 25f));
        }
        public int getValue()
        {
            int value = 0;

            foreach (Triominoe t in triominoes)
            {
                if (t != null)
                    value += t.getValue();
            }

            return value;
        }
        public void update(GameTime gameTime, Triominoe inHand)
        {
            // move triominoes neatly into the bounds of the container
            float dist = gameTime.ElapsedGameTime.Milliseconds * movespeed;

            foreach (Triominoe t in triominoes)
            {
                if (t == null || t == inHand)
                    continue;

                Vector2 d = new Vector2(0);

                if (t.getLocation().X - t.getRadius() < bounds.X)
                    d.X += dist;
                else if (t.getLocation().X + t.getRadius() > bounds.X + bounds.Width)
                    d.X -= dist;
                
                if (t.getLocation().Y - t.getRadius() < bounds.Y)
                    d.Y += dist;
                else if (t.getLocation().Y + t.getRadius() > bounds.Y + bounds.Height)
                    d.Y -= dist;

                t.move(d);
            }
        }
    }
}
